/**
 * 图片优化工具
 * 支持WebP格式、自动压缩、响应式图片等功能
 */
import { ref, computed, onMounted } from 'vue'

/**
 * 检测浏览器是否支持WebP格式
 */
export const supportsWebP = (): Promise<boolean> => {
  return new Promise(resolve => {
    const webP = new Image()
    webP.onload = webP.onerror = () => {
      if (webP.height === 2) {
        resolve(true)
      } else {
        resolve(false)
      }
    }
    webP.src =
      ''
  })
}

/**
 * 获取图片URL的WebP版本
 * @param url 原始图片URL
 * @param useWebP 是否使用WebP
 */
export const getOptimizedImageUrl = async (url: string): Promise<string> => {
  // 如果是相对路径，直接返回
  if (url.startsWith('/') || url.startsWith('./')) {
    return url
  }

  // 如果是完整URL，尝试添加WebP后缀
  if (url.startsWith('http')) {
    const useWebP = await supportsWebP()
    if (useWebP && !url.includes('.webp')) {
      // 检查URL是否已包含查询参数
      const separator = url.includes('?') ? '&' : '?'
      return `${url}${separator}format=webp`
    }
  }

  return url
}

/**
 * 响应式图片生成器
 * @param url 原始图片URL
 * @param sizes 不同尺寸的图片URL
 */
export const generateResponsiveImageSrcset = async (
  url: string,
  sizes: { [key: string]: number }
): Promise<string> => {
  const srcset: string[] = []
  const useWebP = await supportsWebP()

  for (const [suffix, width] of Object.entries(sizes)) {
    // 这里应该由后端生成不同尺寸的图片
    // 示例中假设有相应的图片服务
    const optimizedUrl = url.replace(/(\.[a-zA-Z0-9]+)$/, `_${width}w${useWebP ? '.webp' : '$1'}`)
    srcset.push(`${optimizedUrl} ${width}w`)
  }

  return srcset.join(', ')
}

/**
 * 图片预加载器
 * @param src 图片URL
 */
export const preloadImage = (src: string): Promise<HTMLImageElement> => {
  return new Promise((resolve, reject) => {
    const img = new Image()
    img.onload = () => resolve(img)
    img.onerror = reject
    img.src = src
  })
}

/**
 * LazyImage 组件
 * 封装懒加载图片，支持WebP和响应式
 */
export const LazyImage = {
  props: {
    src: {
      type: String,
      required: true,
    },
    alt: {
      type: String,
      default: '',
    },
    sizes: {
      type: Object,
      default: () => ({
        sm: 320,
        md: 640,
        lg: 1024,
        xl: 1440,
      }),
    },
    aspectRatio: {
      type: String,
      default: '16:9',
    },
  },

  setup(props: any) {
    const imageSrc = ref('')
    const imageSrcset = ref('')
    const isLoaded = ref(false)
    const isError = ref(false)

    const aspectRatioStyle = computed(() => {
      const [w, h] = props.aspectRatio.split(':').map(Number)
      return {
        paddingTop: `${(h / w) * 100}%`,
      }
    })

    onMounted(async () => {
      try {
        // 获取优化的图片URL
        imageSrc.value = await getOptimizedImageUrl(props.src)

        // 生成响应式图片srcset
        if (props.sizes) {
          imageSrcset.value = await generateResponsiveImageSrcset(props.src, props.sizes)
        }

        // 预加载图片
        await preloadImage(imageSrc.value)
        isLoaded.value = true
      } catch (error) {
        console.error('图片加载失败:', error)
        isError.value = true
      }
    })

    return {
      imageSrc,
      imageSrcset,
      isLoaded,
      isError,
      aspectRatioStyle,
    }
  },

  template: `
    <div class="lazy-image" :style="aspectRatioStyle">
      <img
        v-if="imageSrc && !isError"
        :src="imageSrc"
        :srcset="imageSrcset"
        :sizes="'(max-width: 320px) 320px, (max-width: 640px) 640px, (max-width: 1024px) 1024px, 1440px'"
        :alt="alt"
        :class="{ 'is-loaded': isLoaded }"
        @load="isLoaded = true"
        @error="isError = true"
      />
      <div v-if="isError" class="lazy-image__error">
        <svg width="48" height="48" viewBox="0 0 48 48" fill="none">
          <path d="M24 44C35.0457 44 44 35.0457 44 24C44 12.9543 35.0457 4 24 4C12.9543 4 4 12.9543 4 24C4 35.0457 12.9543 44 24 44Z" fill="#f5f5f5"/>
          <path d="M15 24L21 30L33 18" stroke="#d9d9d9" stroke-width="2"/>
        </svg>
        <span>图片加载失败</span>
      </div>
    </div>
  `,
}

/**
 * WebP检测组件
 * 用于条件性渲染WebP或原图
 */
export const WebPImage = {
  props: {
    webpSrc: {
      type: String,
      required: true,
    },
    fallbackSrc: {
      type: String,
      required: true,
    },
    alt: {
      type: String,
      default: '',
    },
  },

  setup(props: any) {
    const currentSrc = ref(props.fallbackSrc)

    onMounted(async () => {
      const webpSupported = await supportsWebP()
      if (webpSupported) {
        currentSrc.value = props.webpSrc
      }
    })

    return {
      currentSrc,
    }
  },

  template: `
    <img :src="currentSrc" :alt="alt" />
  `,
}

/**
 * 图片压缩工具（客户端）
 * 使用Canvas进行图片压缩
 * @param file 文件对象
 * @param quality 压缩质量 (0.1 - 1)
 * @param maxWidth 最大宽度
 * @param maxHeight 最大高度
 */
export const compressImage = (
  file: File,
  quality: number = 0.8,
  maxWidth: number = 1920,
  maxHeight: number = 1080
): Promise<Blob> => {
  return new Promise((resolve, reject) => {
    const canvas = document.createElement('canvas')
    const ctx = canvas.getContext('2d')
    const img = new Image()

    img.onload = () => {
      // 计算压缩后的尺寸
      let { width, height } = img

      if (width > height) {
        if (width > maxWidth) {
          height = (height * maxWidth) / width
          width = maxWidth
        }
      } else {
        if (height > maxHeight) {
          width = (width * maxHeight) / height
          height = maxHeight
        }
      }

      // 设置canvas尺寸
      canvas.width = width
      canvas.height = height

      // 绘制图片
      ctx?.drawImage(img, 0, 0, width, height)

      // 转换为Blob
      canvas.toBlob(
        blob => {
          if (blob) {
            resolve(blob)
          } else {
            reject(new Error('压缩失败'))
          }
        },
        'image/jpeg',
        quality
      )
    }

    img.onerror = reject
    img.src = URL.createObjectURL(file)
  })
}

/**
 * 获取图片格式优先级
 * 返回最优的图片格式列表
 */
export const getImageFormatPriority = async (): Promise<string[]> => {
  const webpSupported = await supportsWebP()

  if (webpSupported) {
    return ['image/webp', 'image/jpeg', 'image/png']
  } else {
    return ['image/jpeg', 'image/png']
  }
}

export default {
  supportsWebP,
  getOptimizedImageUrl,
  generateResponsiveImageSrcset,
  preloadImage,
  LazyImage,
  WebPImage,
  compressImage,
  getImageFormatPriority,
}
